﻿// Tutendle kod napsal Vodacek, snad pomuze i nekomu jinemu
// This piece of code is witten by Vodacek


using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace VodacekEngine
{
    public enum XNBTargetPlatform
    {
        Windows,
        WindowsPhone7,
        Xbox360
    }

    /// <summary>
    /// Stores basic information about XNB file.
    /// </summary>
    public class XNBFileInfo
    {
        public XNBTargetPlatform TargetPlatform
        {
            get;
            private set;
        }

        public byte Version
        {
            get;
            private set;
        }

        public byte FlagBits
        {
            get;
            private set;
        }

        public UInt32 CompressedFileSize
        {
            get;
            private set;
        }

        public UInt32 DecomprossedFileSize
        {
            get;
            private set;
        }

        public bool IsCommpressed
        {
            //   1010 1111
            // & 0000 1111 <-\
            // -----------    |-- same (jsou stejny)
            //   0000 1111 <-/

            get
            {
                return (FlagBits & 0x80) == 0x80;
            }
        }

        public bool IsReach
        {
            get
            {
                return (FlagBits & 0x01) == 0;
            }
        }

        public bool IsHiDef
        {
            get {
                return(FlagBits & 0x01) == 0x01;
            }
        }

        /// <summary>
        ///  Gets XNBFileInfo instance for specified file.
        ///  <returns>Return null if file is not XNB.</returns>
        ///  <param name="fileName">Path to file for inspection.</param>
        /// </summary>
        public static XNBFileInfo GetInfo(string fileName)
        {
            BinaryReader br = new BinaryReader(new FileStream(fileName,FileMode.Open));

            byte[] b=br.ReadBytes(3);
            //         'X'           'N'           'B'
            if (b[0] == 88 && b[1] == 78 && b[2] == 66)
            {
                XNBFileInfo ret = new XNBFileInfo();
                b = br.ReadBytes(3);
                switch(b[0]){
                    case 119:{
                        // w
                        ret.TargetPlatform = XNBTargetPlatform.Windows;
                        break;
                    }

                    case 109:{
                        // m
                        ret.TargetPlatform = XNBTargetPlatform.WindowsPhone7;
                        break;
                    }

                    case 120: {
                        // x
                        ret.TargetPlatform = XNBTargetPlatform.Xbox360;
                        break;
                    }

                    default: {
                        br.Close();
                        return null;
                    }   
                }

                ret.Version = b[1]; // 5= XNA GameStudio 4.0
                ret.FlagBits = b[2]; // set Flag bits

                ret.CompressedFileSize = br.ReadUInt32();
                if (ret.IsCommpressed)
                {
                    ret.DecomprossedFileSize = br.ReadUInt32();
                }
                else
                {
                    ret.DecomprossedFileSize = 0;//not included
                }

                br.Close();
                return ret;
            }
            else
            {
                // todle neni xnb
                br.Close();
                return null;
            }
        }

        private static int Read7BitEncodedInt(BinaryReader br)
        {
            int ret = 0;
            int bitsRead = 0;
            int value;

            do
            {
                value = br.ReadByte();
                ret |= (value & 0x7F) << bitsRead;
                bitsRead += 7;
            }
            while ((value & 0x80)!=0);

            return ret;
        }

        public override string ToString()
        {
            string ret = "XNB ";
            ret += IsCommpressed ? "Compressed file " : "Uncompressed file ";
            ret += "v." + Version + " for ";
            ret += TargetPlatform.ToString();
            ret += IsReach? " Reach profile.":" HiDef profile.";
            return ret;
        }
    }
}
